package com.songaw.generator.modules.globlecache.controller;

import com.songaw.generator.common.conf.redis.RedisUtil;
import com.songaw.generator.common.constant.CacheConstant;
import com.songaw.generator.common.constant.Constant;
import com.songaw.generator.common.pojo.dto.Result;
import com.songaw.generator.modules.globlecache.entity.CacheTable;
import com.songaw.generator.modules.globlecache.pojo.dto.CacheTableDto;
import com.songaw.generator.modules.globlecache.pojo.vo.AddCacheTableVo;
import com.songaw.generator.modules.globlecache.pojo.vo.UpdateCacheTableVo;
import com.songaw.generator.modules.globlecache.service.CacheTableService;
import com.songaw.generator.modules.globlecache.service.GlobleCacheService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * TODO
 *
 * @author songaw
 * @date 2018-21-08  14:21:26
 */
@Api(value = "CacheTable接口", tags = {"CacheTable接口"})
@RestController
@RequestMapping("/v1/cacheTables")
@Slf4j
public class CacheTableController {
    @Autowired
    CacheTableService cacheTableService;

    @Autowired
    GlobleCacheService globleCacheService;

    /**
     * 添加
     *
     * @param vo
     */
    @CacheEvict(value= CacheConstant.CACHE_ALL,allEntries=true)
    @ApiOperation(value = "添加CacheTable", notes = "添加cacheTable")
    @ApiImplicitParam(name = "vo", value = "addCacheTableVo", required = true, dataType = "AddCacheTableVo")
    @ApiResponses({@ApiResponse(code = 400, message = "请求参数错误"), @ApiResponse(code = 404, message = "请求路径没有或页面跳转路径error", response = Result.class)})
    @PostMapping
    public Result<CacheTableDto> addCacheTable(@RequestBody AddCacheTableVo vo) {
        CacheTable cacheTable = new CacheTable();
        BeanUtils.copyProperties(vo, cacheTable);
        cacheTableService.insert(cacheTable);
        CacheTableDto cacheTableDto = new CacheTableDto();
        BeanUtils.copyProperties(cacheTable, cacheTableDto);
        return Result.getSuccessResult(cacheTableDto);
    }

    @ApiOperation(value = "修改CacheTable", notes = "修改cacheTable")
    @ApiImplicitParam(name = "vo", value = "updateCacheTableVo", required = true, dataType = "UpdateCacheTableVo")
    @ApiResponses({@ApiResponse(code = 400, message = "请求参数错误"), @ApiResponse(code = 404, message = "请求路径没有或页面跳转路径error", response = Result.class)})
    @PutMapping
    @CacheEvict(value= CacheConstant.CACHE_ALL,allEntries=true)
    public Result updateCacheTable(@RequestBody UpdateCacheTableVo vo) {
        try {

            Long id = vo.getId();
            if (id == null) {
                return Result.getSystemErrorResult("传入参数错误");
            }
            CacheTable cacheTable = new CacheTable();
            BeanUtils.copyProperties(vo, cacheTable);
            cacheTableService.update(cacheTable);
            return Result.getSuccessResult(null);
        } catch (Exception e) {
            return Result.getSystemErrorResult(e.getMessage());
        }
    }

    @ApiOperation(value = "删除 CacheTable ", notes = "删除 cacheTable ")
    @ApiImplicitParam(name = "id", value = "CacheTableid", required = true, dataType = "String")
    @ApiResponses({@ApiResponse(code = 400, message = "请求参数错误 "), @ApiResponse(code = 404, message = "请求路径没有或页面跳转路径error   ", response = Result.class)})
    @DeleteMapping(value = "/{id}")
    @CacheEvict(value= CacheConstant.CACHE_ALL,allEntries=true)
    public Result deleteCacheTableById(@PathVariable("id") Long id) {
        try {
            CacheTable cacheTable = cacheTableService.selectByPk(id);
            if (cacheTable != null) {
                cacheTableService.deleteByPk(id);
            } else {
                return Result.getSystemErrorResult(" 找不到要删除的数 ");
            }

            return Result.getSuccessResult(null);
        } catch (Exception e) {
            return Result.getSystemErrorResult(e.getMessage());
        }
    }

    @ApiOperation(value = "删除列表 CacheTables", notes = "删除列表 cacheTable ")
    @ApiImplicitParam(name = "ids", value = "cacheTableids:id1,id2,id3", required = true, dataType = "String")
    @ApiResponses({@ApiResponse(code = 400, message = "请求参数错误 "), @ApiResponse(code = 404, message = "请求路径没有或页面跳转路径error   ", response = Result.class)})
    @DeleteMapping(value = "/deleteUserByIds")
    @CacheEvict(value= CacheConstant.CACHE_ALL,allEntries=true)
    public Result deleteCacheTableByIds(@RequestParam("ids") String ids) {
        try {
            String[] idstr = ids.split(",");
            List<Long> idList = new ArrayList<>();
            for (String id : idstr) {
                idList.add(Long.parseLong(id));
            }
            cacheTableService.deleteByPks(idList);
            return Result.getSuccessResult(null);
        } catch (Exception e) {
            return Result.getSystemErrorResult(e.getMessage());
        }
    }

    @ApiOperation("根据ID查询信息")
    @GetMapping(value = "/{id}")
    @ApiImplicitParam(name = "id", value = "CacheTableID", dataType = "Long", paramType = "query")
    @ResponseBody
    public Result<CacheTableDto> getCacheTableById(@PathVariable("id") Long id) {
        CacheTable cacheTable = cacheTableService.selectByPk(id);
        CacheTableDto cacheTableDto = new CacheTableDto();
        BeanUtils.copyProperties(cacheTable, cacheTableDto);
        return Result.getSuccessResult(cacheTableDto);
    }

    @ApiOperation(value = " 列表查询 ", notes = " 列表查询 ")
    @ApiResponses({@ApiResponse(code = 400, message = "请求参数错误 "), @ApiResponse(code = 404, message = "请求路径没有或页面跳转路径error   ", response = Result.class)})
    @RequestMapping(path = "/list", method = RequestMethod.GET)
    public Result<List<CacheTable>> findCacheTables() {
        List<CacheTable> list = cacheTableService.getCacheTableList();
        return Result.getSuccessResult(list);
    }

    @ApiOperation(value = "清空缓存 ", notes = "清空缓存")
    @ApiImplicitParam(name = "id", value = "CacheTableid", required = true, dataType = "String")
    @ApiResponses({@ApiResponse(code = 400, message = "请求参数错误 "), @ApiResponse(code = 404, message = "请求路径没有或页面跳转路径error   ", response = Result.class)})
    @PutMapping(value = "/clear/{id}")
    public Result clearCacheTableById(@PathVariable("id") Long id) {
        try {
            CacheTable cacheTable = cacheTableService.selectByPk(id);
            if (cacheTable != null) {
                globleCacheService.clearCache(cacheTable);
            } else {
                return Result.getSystemErrorResult(" 找不到要清空的缓存 ");
            }

            return Result.getSuccessResult(null);
        } catch (Exception e) {
            return Result.getSystemErrorResult(e.getMessage());
        }
    }

    @ApiOperation(value = "刷新缓存 ", notes = "刷新缓存")
    @ApiImplicitParam(name = "id", value = "CacheTableid", required = true, dataType = "String")
    @ApiResponses({@ApiResponse(code = 400, message = "请求参数错误 "), @ApiResponse(code = 404, message = "请求路径没有或页面跳转路径error   ", response = Result.class)})
    @GetMapping(value = "/refresh/{id}")
    public Result refreshCacheCacheTableById(@PathVariable("id") Long id) {

        if (id == 0L) {
            //刷新所有没有依赖的缓存
            List<CacheTable> list = cacheTableService.selectAll();
            //所有没有依赖的缓存
            list = list.stream().filter(item -> StringUtils.isBlank(item.getParentName()) || !Constant.CODE_DELETE_FLAG_0.equals(item.getDeleteFlag())).collect(Collectors.toList());
            list.stream().forEach(item ->{
                try {
                    globleCacheService.refreshCache(item);
                }catch (Exception e){
                    e.printStackTrace();
                }
            });
            return Result.getSuccessResult(null);
        }
        CacheTable cacheTable = cacheTableService.selectByPk(id);
        if (cacheTable != null) {
            if (cacheTable.getParentName() != null) {
                return Result.getSystemErrorResult("此缓存刷新需要父级依赖");
            }
            globleCacheService.refreshCache(cacheTable);

        } else {
            return Result.getSystemErrorResult("找不到要刷新的缓存");
        }

        return Result.getSuccessResult(null);
    }



    @GetMapping(value = "/refreshAll")
    @Scheduled(cron = "0 0 1 ? * *")
    public Result refreshCacheCacheTable() {
        Long id = 0L;
        log.info("刷新缓存 start" + id);

        RLock lock = RedisUtil.getRedisson().getLock("refreshCache" + id);
        log.info("试图获得锁refreshCache" + id);
        boolean res = false;

        try {
            res = lock.tryLock(3, TimeUnit.SECONDS);
            if (res) {
                log.info("获得锁：refreshCache" + id);
                refreshCacheCacheTableById(id);
            } else {
                log.info("没有获得锁：refreshCache" + id);
                return Result.getSystemErrorResult("正在刷新缓存中");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            return Result.getSystemErrorResult("正在刷新缓存中");
        } finally {
            try {
                if (res) {
                    lock.unlock();
                    log.info("释放了锁：refreshCache" + id);
                }
            } catch (Exception e2) {
                log.error(e2.getMessage());
            }
        }

        log.info("刷新缓存 end");
        return Result.getSuccessResult(null);
    }
}
